home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Skunkware 5
/
Skunkware 5.iso
/
src
/
Games
/
connx-1.0
/
client.c
next >
Wrap
C/C++ Source or Header
|
1995-07-05
|
6KB
|
317 lines
/*
* client main loop for connX
*/
#include <pwd.h>
#include "commun.h"
#include <stdio.h>
#include "connect.h"
#include <strings.h>
#include "xconnect.h"
#include <errno.h>
#include <sys/types.h>
#include <sys/time.h>
#ifdef AIX
#include <sys/select.h>
#endif
#define CHECK_RC(rc) if (rc==-1) { printf("Server exited\n"); client_exit(); }
#define NUM_FLAGS 3
enum
{
F_NAME, F_DISPLAY, F_HOST
};
int flags_val[] =
{F_NAME, F_DISPLAY, F_HOST};
char *flags_txt[] =
{"-name", "-display", "-host"};
/*prototypes */
void usage (char *prog);
int parse_args (int argc, char **argv, char **pName, char **pDisplay_name,
char **pHost);
void play_games ();
void connect_to_server (char *pName);
int to_flag (char *string);
void client_exit ();
/*globals*/
int fd;
char *program_name;
/*****************************************************************************/
main (int argc, char **argv)
{
int rc;
char *pDisplay_name = NULL;
char *pName = NULL;
char *pHost = NULL;
struct passwd *pInfo;
char host[80];
if (parse_args (argc, argv, &pName, &pDisplay_name, &pHost) == -1)
{
usage (argv[0]);
exit (1);
}
program_name = argv[0];
if (X_open (pDisplay_name) == -1)
exit (1);
#ifdef TCPIP
if (pHost == NULL) /* use local host */
{
gethostname (host, 80);
printf("Using %s as host\n",host);
pHost = host;
}
#endif
rc = client_open_connection (&fd, pHost);
if (rc != 0)
{
printf ("Can\'t connect\n");
exit (1);
}
/* get default player name = userid */
if (pName == NULL)
{
pInfo = getpwuid (getuid ());
pName = pInfo->pw_name;
}
connect_to_server (pName);
play_games ();
}
/****************************************************************************/
/* internals ***************************************************************/
/**************************************************************************/
/*
* send connection message to server
*/
void
connect_to_server (char *pName)
{
new_player new_p;
int rc;
strcpy (new_p.name, pName);
rc = send_message (&fd, NEW_PLAYER, sizeof (new_player), (char *) &new_p);
CHECK_RC (rc);
}
/***********************************************************************/
/*
* play games of connX - exit when server exits or player selects quit
*/
void
play_games ()
{
gen_msg msg_recv;
game_start *start;
char data[MAX_DATA];
int my_num;
my_move mymove;
my_move *mymove_resp;
others_move *othersmove;
game_end *game_over;
int rc, num;
struct fd_set readfs;
struct timeval notimeout;
whose_move *whose;
msg_recv.msg = (char *) &data;
notimeout.tv_sec = 0;
notimeout.tv_usec = 0;
while (1)
{
FD_ZERO (&readfs);
FD_SET (fd, &readfs);
/* handle expose, resize */
if (X_handle_events () == QUIT)
client_exit ();
/* has to be non blocking to handle X-events */
if ((num = select (fd + 1, &readfs, NULL, NULL, ¬imeout)) < 0)
{
printf ("select error\n");
exit (1);
}
if (num > 0)
{ /* handle incoming message */
rc = read_message (&fd, &msg_recv);
CHECK_RC (rc);
switch (msg_recv.msg_type)
{
case GAME_START:
start = (game_start *) msg_recv.msg;
my_num = start->your_number;
X_allocate (*start);
break;
case YOUR_MOVE:
rc = X_get_player_move (&mymove.move);
if (rc == QUIT)
client_exit ();
if (rc == FORFEIT)
{
mymove.move.row = FORFEIT;
mymove.move.column = FORFEIT;
}
rc = send_message (&fd, MY_MOVE, sizeof (mymove), (char *) &mymove);
CHECK_RC (rc);
break;
case MY_MOVE:
mymove_resp = (my_move *) msg_recv.msg;
if (mymove_resp->rc == -1)
X_bad_move ();
else
X_add_to_board (mymove_resp->move, my_num);
break;
case OTHERS_MOVE:
othersmove = (others_move *) msg_recv.msg;
if (othersmove->player_number != my_num)
X_add_to_board (othersmove->move, othersmove->player_number);
break;
case WHOSE_MOVE:
whose = (whose_move *) msg_recv.msg;
X_show_turn (whose->player);
break;
case GAME_END:
game_over = (game_end *) msg_recv.msg;
X_game_end (game_over->winner, game_over->connect[0],
game_over->connect[1]);
break;
default:
printf ("Comm problem %d\n", msg_recv.msg_type);
exit (1);
}
}
}
}
/*************************************************************************/
/* command line processing */
int
parse_args (int argc, char **argv, char **pName, char **pDisplay_name,
char **pHost)
{
int i;
int flag;
if (((argc - 1) % 2) != 0)
return -1;
for (i = 1; i < argc; i = i + 2)
{
flag = to_flag (argv[i]);
switch (flag)
{
case F_DISPLAY:
*pDisplay_name = argv[i + 1];
break;
case F_NAME:
*pName = argv[i + 1];
break;
case F_HOST:
*pHost = argv[i + 1];
break;
default:
return -1;
}
}
return 0;
}
/*****************************************************************************/
int
to_flag (char *string)
{
int i;
for (i = 0; i < NUM_FLAGS; i++)
if (strcmp (string, flags_txt[i]) == 0)
return flags_val[i];
return -1;
}
/**************************************************************************/
void
usage (char *prog)
{
int i;
printf ("Usage: %s \n", prog);
printf ("-name <player_name>\n");
printf ("-display <display>\n");
printf ("-host <host>\n\n\n");
}
/********************************************************************/
/*
* check if server cancelled move
* Note: if server cancels game, next message on queue indicates so
*/
int
move_cancelled ()
{
int rc;
gen_msg msg_recv;
struct fd_set readfs;
struct timeval notimeout;
char data[MAX_DATA];
msg_recv.msg = (char *) &data;
notimeout.tv_sec = 0;
notimeout.tv_usec = 0;
FD_ZERO (&readfs);
FD_SET (fd, &readfs);
if (select (fd + 1, &readfs, NULL, NULL, ¬imeout) > 0)
{
rc = read_message (&fd, &msg_recv);
CHECK_RC (rc);
if (msg_recv.msg_type == CANCEL_MOVE)
/* cancelled */
return 1;
}
/* not cancelled */
return 0;
}
/***********************************************************************/
/*
* terminate client
*/
void
client_exit ()
{
X_deallocate ();
X_close ();
close (fd);
exit (0);
}